package com.sola.serviceapi.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

@Configuration
@EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {

    private static final String DEMO_RESOURCE_ID = "order";

    @Autowired
    RedisConnectionFactory redisConnectionFactory;
    //获取yml中的密钥值
    @Value("${security.oauth2.resource.jwt.key-value}")
    private String SigningKey;

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
        //sola-town为对称加密的密钥，所有需要解析JWT的微服务都需要持有这个密钥
        accessTokenConverter.setSigningKey(SigningKey);
        return accessTokenConverter;
    }
    @Bean
    public TokenStore myTokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            //resourceId 用于分配给可授予的clientId
            //stateless  标记以指示在这些资源上仅允许基于令牌的身份验证
            //tokenStore token的存储方式（上一章节提到）
            resources
                    .resourceId(DEMO_RESOURCE_ID)
                    .stateless(true)
                    .tokenStore(myTokenStore());
        }

        //设置具体的访问拦截规则。
        @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                    // 我们希望在UI中也能访问受保护的资源
                    // 允许创建session， (2.X中默认是禁止)
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                    .and()
                    .requestMatchers().anyRequest()
                    .and()
                    .anonymous()
                    .and()
                    .authorizeRequests()
//                    .antMatchers("/product/**").access("#oauth2.hasScope('select') and hasRole('ROLE_USER')")
                    //设置了拦截路径
                    //必须认证过后才可以访问
                    .antMatchers("/**").authenticated();
            // @formatter:on
        }
    }

